package myjava.test.xml.reader.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;

/**
 * 读取xml文档的结构及所含的信息 在需要时才获取对象信息
 * 
 * @author zichaoyang
 *
 */
public abstract class XmlReader extends BeanContext {

	/**
	 * TODO 下面这种数据结构待修改 从xml文档中读取的类的路径 List是一个含有类信息的列表 Map是一个存储类路径及其初始化路径的map
	 * LinkedList 是一个存储类初始化数据的列表 里面的map以属性名为键值，?表示可以为对象或者字符串，或者整形等等
	 */
	protected List<Map<String, LinkedList<Map<String, ?>>>> beanMessage;

	/**
	 * 查询节点为bean，即 <bean id="" class=""> <value name="">***<value> 表示一个属性的值
	 * <value name="" ref="" /> 表示一个对象的值，ref指向另一个bean的id </bean>
	 */
	private final static String BEAN = "bean";

	private final static String NAME = "name";

	private final static String REF = "ref";

	private final static String ID = "id";

	private final static String CLASS = "class";

	public XmlReader(String path) {
		super(path);
		this.beanMessage = new ArrayList<>();
	}

	public XmlReader(String path, boolean isRootPath) {
		super(path, isRootPath);
		this.beanMessage = new ArrayList<>();
	}

	@Override
	public abstract void addBeanMessage(Map<String, LinkedList<Map<String, ?>>> beanMessage);

	/**
	 * TODO test
	 */
	@Override
	public Map<String, LinkedList<Map<String, ?>>> getBeanMessage(String id) {
		// 获得目标对象节点
		Element element = this.getElement(BEAN, ID, id);
		return this.getBeanMessage(element);
	}

	@Override
	public Map<String, LinkedList<Map<String, ?>>> getBeanMessage(Element element) {
		// 获得该节点的所有子节点，及一个对象所有属性值
		List<Element> sonElements = this.getSonElement(element);
		Map<String, LinkedList<Map<String, ?>>> maps = new HashMap<>();
		LinkedList<Map<String, ?>> lists = new LinkedList<>();
		for (Element e : sonElements) {
			// 获得属性名
			String attributeValue = e.attributeValue(NAME);
			// 判断该属性是不是一个对象
			String ref = e.attributeValue(REF);
			// 不是对象
			if (ref == null) {
				// TODO 加一个是否为整形或布尔值等等的判断，或是在反射是判断
				if (e.elements().size() != 0) {
					Map<String, Map<String, ?>> map = new HashMap<>();
					lists.add(this.getMapBean(e.attributeValue("name")));
				} else {
					Map<String, String> map = new HashMap<>();
					map.put(attributeValue, e.getTextTrim());
					lists.add(map);
				}
			} else {// ...................................是对象
				Map<String, Map<String, ?>> map = new HashMap<>();
				map.put(attributeValue, this.getBeanMessage(ref));
				lists.add(map);
			}
		}
		maps.put(element.attributeValue(CLASS) + "&" + element.attributeValue(ID), lists);
		return maps;
	}

	public Map<String, List<Map<String, String>>> getMapBean(String id) {
		Element element = this.getElement("value", NAME, id);
		List<Map<String, String>> lists = new ArrayList<>();
		for (Element e : this.getSonElement(element)) {
			// 获得属性名
			String attributeValue = e.attributeValue(NAME);
			// 判断该属性是不是一个对象
			String ref = e.attributeValue(REF);
			if(ref == null){
				Map<String, String> map = new HashMap<>();
				map.put(attributeValue, e.getTextTrim());
				lists.add(map);
			}
		}
		Map<String, List<Map<String, String>>> maps = new HashMap<>();
		maps.put(id, lists);
		return maps;
	}

}
